package com.example.service;

import com.example.exception.NoServerException;
import com.example.utils.DataChange;
import com.example.utils.IPUtils;
import com.example.utils.Pong;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.io.ObjectInputStream;
import java.net.HttpURLConnection;
import java.net.URL;

@Service
public class TestServiceImpl implements TestService, InitializingBean, DisposableBean {

    public static final int MAX_SERVER_ID = 9999;
    private static final String URL_PREFX = "http://";
    Logger logger = LoggerFactory.getLogger(getClass());
    private volatile boolean isStop = false;
    private Thread thread;

    @Value("${server.port}")
    private int port;

    @Value("${server.appKey}")
    private String appKey;

    private String serverUrl;

    @Resource
    private SysClusterService sysClusterService;

    @Override
    public void destroy() throws Exception {
        this.isStop = true;
        if (this.thread.isAlive()) {
            this.thread.interrupt();
        }
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        this.thread = new Thread(new Runnable() {
            @Override
            public void run() {
                logger.warn("config refresh thread start ...");
                while (!isStop) {
                    HttpURLConnection connection = null;
                    try {
                        URL url = new URL(buildPingUrl());
                        connection = (HttpURLConnection) url.openConnection();
                        connection.setReadTimeout(310000);
                        connection.setConnectTimeout(3000);
                        connection.setRequestMethod("GET");
                        if (HttpURLConnection.HTTP_OK == connection.getResponseCode()) {
                            ObjectInputStream inputStream = null;
                            try {
                                inputStream = new ObjectInputStream(connection.getInputStream());
                                Object object = inputStream.readObject();
                                if (object != null && object instanceof Pong) {
                                    logger.warn("接收到心跳包: " + object);
                                }
                                if (object != null && object instanceof DataChange) {
                                    logger.warn("收到配置变化: " + object);
                                }
                            } finally {
                                if (inputStream != null) {
                                    inputStream.close();
                                }
                            }
                        }
                    } catch (Exception e) {
                        if (e instanceof NoServerException) {
                            logger.warn("当前不存在活跃的服务节点 ...");
                        } else {
                            logger.warn("服务端: " + serverUrl + " 连接失败，将自动重试重连");
                        }
                        serverUrl = null;
                    } finally {
                        if (connection != null) {
                            connection.disconnect();
                        }
                    }
                }
            }
        });
        this.thread.setName("refresh-thread");
        this.thread.start();
    }

    /****
     * 构建心跳请求连接
     * @return
     */
    @Override
    public String buildPingUrl() throws Exception {
        if (StringUtils.isEmpty(this.serverUrl)) {
            this.serverUrl = sysClusterService.getServer();
        }
        return URL_PREFX + this.serverUrl + "/" + appKey + "/" + IPUtils.getLocalIP() + ":" + port + "/" + System.currentTimeMillis();
    }
}
